import subprocess
import re
import os
import shutil
import time
import signal

# import ..global_vars.globalvars
from ..global_vars import globalvars

import importlib.util
import importlib
import sys
from pdb import set_trace as stx


def get_process_pid(proc):
    """获取子进程的PID。"""
    if hasattr(proc, "pid"):
        return proc.pid
    else:
        # 对于Windows或其他不直接提供pid属性的平台，尝试这种方式获取
        return proc._child_fd.fileno()


def send_signal_to_child(proc, signum):
    """向子进程发送信号。"""
    pid = get_process_pid(proc)
    try:
        os.kill(pid, signum)
    except ProcessLookupError:
        print(f"进程{pid}已不存在，无法发送信号。")
    except PermissionError:
        print("没有权限发送信号到该进程。")


def func(*arg):
    globalvars.progress = []
    current_path = "bs_code/data"
    # abs_directory_path = os.path.abspath(current_path)

    if os.path.exists(current_path):
        # 删除目录及其内容
        shutil.rmtree(current_path)
        # 重新创建目录
        os.makedirs(current_path)
        print(f"Cleared all contents in the directory: {current_path}")
    else:
        print(f"The directory does not exist: {current_path}")

    command_path = "bs_code/recover.py"
    command = ["python3", "-u", "recover.py", "--steps", "30", "myload"]
    command[2] = command_path
    name = "cutfilter_Kyber768Simplified_seed7175"
    name = arg[0]

    command[4] = str(arg[3])

    args = [
        "inequalities/filtered/cutfilter_Kyber768Simplified_seed7175",
        "10",
        "True",
        "768",
    ]
    args_path = "bs_code/inequalities/" + (
        "filtered" if name[0] == "c" else "unfiltered"
    )
    args[0] = args_path + "/" + name
    args[1] = str(arg[2])
    args[2] = str(arg[1])
    s = name
    str_list = re.findall(r"\d+", s)
    # print(str_list)
    args[3] = str_list[0]

    # 运行命令，捕获输出
    process = subprocess.Popen(
        command + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
    )

    num1 = 0
    final_line = ""

    try:
        while globalvars.message == "start":
            next_line = process.stdout.readline()
            if next_line == "" and process.poll() is not None:
                break
            # print(next_line)
            if "changheng" in next_line:
                if "False" in next_line:
                    final_line = next_line
                    break
                elif "True" in next_line:
                    final_line = next_line
                    break
                else:
                    s = next_line
                    str_list = re.findall(r"\d+", s)
                    int_list = [int(s) for s in str_list]
                    # print(int_list[0], end=' ')
                    num1 = int_list[0]
            elif "changyesheng" in next_line:
                s = next_line
                str_list = re.findall(r"\d+", s)
                int_list = [int(s) for s in str_list]
                # print(int_list[0])
                globalvars.progress.append({"progress": num1, "recovered": int_list[0]})

        if globalvars.message != "start":
            print("尝试优雅地终止子进程...")
            send_signal_to_child(process, signal.SIGTERM)  # 发送SIGTERM信号
            try:
                process.wait(timeout=5)  # 等待子进程响应信号并终止
            except subprocess.TimeoutExpired:
                print("子进程未响应SIGTERM，将尝试强制终止...")
                send_signal_to_child(process, signal.SIGKILL)  # 如果超时，则发送SIGKILL
                process.wait()  # 确保子进程被终止

    except Exception as e:
        print(f"出现异常: {e}")
        send_signal_to_child(process, signal.SIGKILL)  # 发生异常时强制终止
        process.wait()

    finally:
        process.wait()
        if "False" in final_line:
            s = final_line
            str_list = re.findall(r"\d+", s)
            int_list = [int(s) for s in str_list]
            globalvars.progress.append({"progress": "False", "recovered": int_list[-1]})
            print(globalvars.progress.append)
            # print("False")
            # print(int_list[-1])
        elif "True" in final_line:
            s = final_line
            str_list = re.findall(r"\d+", s)
            int_list = [int(s) for s in str_list]
            globalvars.progress.append({"progress": "True", "recovered": int_list[-1]})
            print(globalvars.progress.append)
            # print("True")
            # print(int_list[-1])
        time.sleep(1)
        globalvars.message = "stop"
        error_output = process.stderr.read()
        if error_output:
            print("错误输出:")
            print(error_output)

    return 0


def func2(*arg):

    # 获取当前工作目录
    current_path = os.getcwd()
    print(current_path)
    current_path = current_path + "/bs_code/data"
    print(current_path)

    # 获取当前路径下所有文件和文件夹
    all_entries = os.listdir(current_path)
    # print(all_entries)

    folders = [
        entry
        for entry in all_entries
        if os.path.isdir(os.path.join(current_path, entry))
    ]
    real_path = current_path + "/" + folders[0]
    print(real_path)

    # 前端传入参数
    # int_step = 4
    # index_l = 2
    # index_r = 4

    int_step = arg[2]
    index_l = arg[0]
    index_r = arg[1]

    # int_step = steps
    # index_l = startIndex
    # index_r = endindex

    # 得到step_data文件路径
    # py_path = real_path + '/step_' + str(int_step) + '/step_data.py'
    # print(py_path)
    # 得到run_data文件路径
    # run_data_path = real_path + '/run_data.py'
    # print(run_data_path)

    module_path = real_path
    sys.path.append(module_path)

    # 引入run_data
    import run_data

    # print(run_data.key[index_l:index_r])

    # 引入step_data
    module_step_file = f"{module_path}/step_{int(int_step)}/step_data.py"
    # print(module_step_name)
    print(module_step_file)

    # spec = importlib.util.find_spec(module_step_name)
    spec = importlib.util.spec_from_file_location(
        f"step_{int(int_step)}_step_data", module_step_file
    )
    if spec is None:
        raise ImportError(f"Module {module_step_file} not found")

    # 加载模块
    module_step = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module_step)

    var_name = "dists_" + str(int_step)

    # if var_name in globals():
    #     var_step = globals()[var_name]
    #     print("Yes")
    # else:
    #     print("No")
    if hasattr(module_step, var_name):
        variable_value = getattr(module_step, var_name)
        print("yes")
    else:
        print("no")

    # print(variable_value[index_l:index_r])

    globalvars.dist = variable_value[index_l:index_r]
    # print(globalvars.dist)
    globalvars.key = run_data.key[index_l:index_r]
    globalvars.message = "stop"
    return 0
